
var component={install:function(ap,obj){//自定义组件
    ap.component('m-page',{
        template:`
        <div>
            <div v-if="title" class="cu-bar fixed bg-gradual-blue" :style="{height:height+'px'}">
                <div v-if="!hideBack" class="action" @click="$emit('back')">
                    <span class="cuIcon-back" style="margin-top:3px;"></span> 返回
                </div>
                <div v-if="title" class="content" :style="{height:height+'px',lineHeight:height+'px'}">
                    {{title}}
                </div>
                <div v-if="home" class="action" @click="toHome">
                    <span class="cuIcon-home"></span> 首页
                </div>
            </div>
            <div v-if="showNav" class="fixed nav" :style="{top:height+'px'}"><slot name="nav"></slot></div>
            <div :style="{paddingTop:height+'px'}"></div>
            <div :style="{paddingTop:showNav?'45px':'',paddingBottom:showBar?'50px':''}">
                <slot></slot>
            </div>
            <div v-if="showBar" class="cu-bar bg-white border foot"><slot name="bar"></slot></div>
        </div>
        `,
        props:{
            title:{type:String,default:''},
            home:{type:Boolean,default:false}
        },
        data() {
            return {
                height:this.title?50:0,
                showNav:false,
                showBar:false,
                hideBack:false
            };
        },
        mounted(){
			if(this.$slots.nav) this.showNav=true;
			if(this.$slots.bar) this.showBar=true;
			if(!config.pageBackFlag){
			    config.pageBackFlag=true;
			    this.hideBack=true;
			}
        },
        methods:{
            toHome:function(){
                location.href="/";
            }
        }
    });
    ap.component('m-card',{
        template:`<div class="cu-card case" :style="{marginTop:join?'-15px':'0'}">
            <div :class="['cu-item','bg-'+color,(light?'light':''),(color&&light?'shadow-blur':'')]">
                <slot></slot>
            </div>
        </div>`,
        props:{
			'color':{type:String,default:'white'},//red orange yellow olive green cyan ...
			'light':{type:Boolean,default:false},
			'join':{type:Boolean,default:false}
		}
    });
    ap.component('m-alert',{
        template:`<m-card :color="color" :light="light" :join="join">
            <div class="flex align-center">
                <div v-if="icon" class="padding-sm">
                    <m-icon :name="icon"></m-icon>
                </div>
                <div :class="[icon?'':'padding-left']" class="flex-sub padding-tb-sm padding-right text-content">
                    <slot></slot>
                </div>
            </div>
        </m-card>`,
		props:{
			'color':{type:String,default:'white'},//red orange yellow olive green cyan ...
			'icon':{type:String},
			'light':{type:Boolean,default:true},
			'join':{type:Boolean,default:false}
		}
    });
    ap.component('m-cell',{
        template:`<div class="flex align-center padding-sm m-cell">
            <div v-if="showIcon" class="padding-right-sm"><slot name="icon"></slot></div>
            <div class="flex-sub padding-right-sm"><slot></slot></div>
            <div class="text-right"><slot name="action"></slot></div>
        </div>`,
		props:{
		},
		data() {
			return {
				showIcon:false,
			};
		},
		mounted(){
			if(this.$slots.icon) this.showIcon=true;
		}
    });
    ap.component('m-desc',{
        template:`<div class="text-df">
            <div :class="'margin-'+margin+' '+'padding-'+padding+' '+innerClass">
                <div v-if="title" class="text-blue text-sm">{{title}}</div>
                <div><slot name="title"></slot></div>
                <div style="min-height:18px;padding-top:2px;"><slot></slot></div>
            </div>
        </div>`,
		props:{
			'title':{type:String,default:''},
			'margin':{type:String,default:'xs'},
			'padding':{type:String,default:''},
			'innerClass':{type:String,default:''}
		}
    });
    ap.component('m-grid',{
        template:`<div class="grid align-center" :class="['col-'+col]">
            <div v-for="(item,k) in items" :key="k" :style="{width:(99.99/col*(item.span||1))+'%'}">
                <slot :item="item" name="item"></slot>
            </div>
            <slot></slot>
        </div>`,
        props:{
			'col':{type:Number,default:3},
			'items':{type:Array,default:[]}
		}
    });
    ap.component('m-icon',{
        template:`<div class="flex align-center justify-center" :style="{height:size+'px'}">
            <img :src="'resources/icons/'+name+'.png'" class="m-icon" :style="{width:size+'px',height:size+'px'}"></img>
            <div :style="{fontSize:(size*0.5)+'px'}"><slot></slot></div>
        </div>`,
		props:{
			'name':{type:String,default:''},//
			'size':{type:Number,default:32}
		}
    });
    ap.component('m-list',{
        template:`<div :style="{paddingBottom:bottom+'px'}">
            <div v-if="error">
                <m-alert icon="error" color="red">
                    <div class="text-bold text-lg">查询失败</div>
                    <div>{{error}}</div>
                </m-alert>
                <slot name="error"></slot>
            </div>
            <template v-else>
                <slot name="top"></slot>
                <template v-if="selfItems">
                    <slot :items="list" name="items"></slot>
                </template>
                <template v-else>
                    <div v-for="(item,k) in list" :key="k">
                        <slot :item="item" name="item"></slot>
                    </div>
                </template>
                <div v-if="list.length" class="padding-bottom text-grey text-center text-sm text-shadow">
                    <div v-if="pageIndex!=pageCount">下一页更精彩...</div>
                    <div v-else>- 没有下一页了 -</div>
                </div>
                <div v-else-if="!isLoad" class="text-center margin" style="padding-top:30px;">
                    <m-icon name="nodata" :size="64"></m-icon>
                    <div class="padding text-grey padding-left-sm">暂无数据</div>
                </div>
                <div v-if="isLoad&&loadIndex==0" class="cu-load loading text-blue"></div>
                <slot></slot>
                <div style="padding-top:50px;"></div>
            </template>
            <div class="cu-bar bg-white tabbar border foot" style="left:0;">
                <div class="action" style="flex:3;text-align:right;padding-right:15px;">
                    <div class="padding-bottom-xs">共<span class="text-blue padding-lr-xs text-df">{{count}}</span>条记录</div>
                    <div>当前第<span class="text-blue padding-lr-xs text-df">{{pageIndex}}</span>页，共<span class="text-blue padding-lr-xs text-df">{{pageCount}}</span>页</div>
                </div>
                <div class="action text-blue" @click="pageSizeModal=true;">
                    <span v-if="isLoad&&loadIndex==1" class="cuIcon-loading2 cuIconfont-spin"></span>
                    <span v-else class="cuIcon-sort shadow"></span> {{page.num}}条
                </div>
                <div class="action text-blue" v-if="search.length" @click="openSearch();">
                    <span v-if="isLoad&&loadIndex==2" class="cuIcon-loading2 cuIconfont-spin"></span>
                    <span v-else class="cuIcon-filter shadow">
                        <span v-if="searchNum" class="cu-tag badge" style="right:0;">{{searchNum}}</span>
                    </span> 筛选
                </div>
                <div class="action" :class="pageIndex==1?'text-gray':'text-blue'" @click="loadIndex=3;prePage();">
                    <span v-if="isLoad&&loadIndex==3" class="cuIcon-loading2 cuIconfont-spin"></span>
                    <span v-else class="cuIcon-pullleft shadow"></span> 上一页
                </div>
                <div class="action" :class="pageIndex==pageCount||pageCount==0?'text-gray':'text-blue'" @click="loadIndex=4;nextPage();">
                    <span v-if="isLoad&&loadIndex==4" class="cuIcon-loading2 cuIconfont-spin"></span>
                    <span v-else class="cuIcon-pullright shadow"></span> 下一页
                </div>
            </div>
            <div class="cu-modal" :class="pageSizeModal?'show':''" @click="pageSizeModal=false">
                <div class="cu-dialog page-size-modal padding-sm" @click.stop="">
                    <div class="padding-xs text-bold text-left text-blue margin-bottom-xs solid-bottom">每页显示：</div>
                    <template v-for="(item,i) in pageSizeOption" :key="i">
                        <div @click="loadIndex=1;page.num=item;query(1);" class="padding-xs light radius" :class="item==page.num?'bg-blue':''">{{item}}条</div>
                    </template>
                </div>
            </div>
            <m-modal ref="search" title="筛选条件">
                <m-card>
                    <div v-for="(item,k) in search" :key="k" class="cu-form-group">
                        <div class="title">{{item.title}}</div>
                        <m-input v-if="item.input=='text'" v-model="searchParams[item.name]" :placeholder="'请输入'+item.title"></m-input>
                        <m-input-number v-else-if="item.input=='number'" v-model="searchParams[item.name]" :placeholder="'请输入'+item.title"></m-input-number>
                        <m-select-dict v-else-if="item.input=='dict'" class="flex-sub" v-model="searchParams[item.name]" :type="item.dict" :placeholder="'请选择'+item.title"></m-select-dict>
                        <m-select-date v-else-if="item.input=='date'" class="flex-sub" v-model="searchParams[item.name]" :placeholder="'请选择'+item.title"></m-select-date>
                        <div v-else-if="item.input.indexOf('Range')>0" class="flex-sub flex">
                            <m-input-number v-if="item.input=='numberRange'" v-model="searchParams[item.name+'@ge']" :placeholder="'请输入起'"></m-input-number>
                            <m-select-date v-else-if="item.input=='dateRange'" class="flex-sub" v-model="searchParams[item.name+'@ge']" :placeholder="'请选择起'"></m-select-date>
                            <div class="padding-lr-xs">~</div>
                            <m-input-number v-if="item.input=='numberRange'" v-model="searchParams[item.name+'@le']" :placeholder="'请输入至'"></m-input-number>
                            <m-select-date v-else-if="item.input=='dateRange'" class="flex-sub" v-model="searchParams[item.name+'@le']" :placeholder="'请选择至'"></m-select-date>
                        </div>
                    </div>
                </m-card>
                <div class="flex padding-lr-sm padding-bottom">
                    <div class="flex-sub flex flex-direction padding-lr-xs">
                        <m-button @click="resetParams()" line>重置</m-button>
                    </div>
                    <div class="flex-sub flex flex-direction padding-lr-xs">
                        <m-button @click="loadIndex=2;searchQuery(1)">查询</m-button>
                    </div>
                </div>
            </m-modal>
        </div>`,
		props:{
			url:{type:String,default:''},
			params:{type:Object,default:{}},
			bottom:{type:Number,default:50},
			search:{type:Array,default:[]}//{title:'',name:'',input:(text,dict),dict:''}
		},
		data() {
			return {
				selfItems:false,//自己循环
				list:[],
				count:0,//总记录数
				pageCount:1,//总页数
				pageIndex:1,//当前页数
				page:{index:0,num:20},//分页（index:开始记录数，num:每页数量）
				searchNum:0,
				searchParams:{},
				isLoad:false,
				loadIndex:0,
				error:'',
				pageSizeModal:false,
				pageSizeOption:[5,10,20,50,100,200]
			};
		},
		mounted(){
			if(this.$slots.items) this.selfItems=true;
			this.$nextTick(()=>{
                for(var k in this.params){
                    this.searchParams[k]=this.params[k];
                }
                setTimeout(()=>this.searchQuery(1),15);
			});
		},
		methods:{
			prePage:function(){
				if(this.pageIndex==1) return;
				this.searchQuery(this.pageIndex-1);
			},
			nextPage:function(){
				if(this.pageIndex==this.pageCount||this.pageCount==0) return;
				this.searchQuery(this.pageIndex+1);
			},
			openSearch:function(){
				for(var k in this.params){
					this.searchParams[k]=this.params[k];
				}
				this.$refs.search.open();
			},
			closeSearch:function(){
				this.searchParams={};
				this.$refs.search.close();
			},
			resetParams:function(){
				for(let i=0;i<this.search.length;i++){
				    if(this.search[i].input.indexOf('Range')>0){
                        this.searchParams[this.search[i].name+'@ge']=null;
                        this.searchParams[this.search[i].name+'@le']=null;
				    }else{
					    this.searchParams[this.search[i].name]=null;
				    }
				}
			},
			searchQuery:function(pn){
				this.searchNum=0;
				for(var k in this.searchParams){
					this.params[k]=this.searchParams[k];
				}
				for(let i=0;i<this.search.length;i++){
				    if(this.search[i].input.indexOf('Range')>0){
				        if(this.params[this.search[i].name+'@ge']||this.params[this.search[i].name+'@le']) this.searchNum++;
				    }else{
					    if(this.params[this.search[i].name]) this.searchNum++;
				    }
				}
				this.query(pn);
				this.$refs.search.close();
			},
			//解决bug  modal关闭时调用
			reset:function(){
				let ls=[];
				for(let i=0;i<this.list.length;i++){
					ls.push(this.list[i]);
				}
				this.list=ls;
			},
			//刷新
			refresh:function(pn){
				this.query(pn||this.pageIndex);
			},
			//获取当前列表
			getList:function(){
				return this.list;
			},
			query:function(pn){
				if(this.isLoad) return;
				this.pageSizeModal=false;
				this.isLoad=true;
				this.page={index:(pn-1)*this.page.num,num:this.page.num};
				this.requestData(this.url,
					{page:this.page,params:this.params},
					(json)=>{
						this.isLoad=false;
						this.loadIndex=0;
						if(json.code==0){
							this.error="";
							this.list=json.page.list;
							this.count=json.page.count;
							this.pageCount=json.page.pageCount;
							this.pageIndex=json.page.pageIndex;
							this.$emit('queryAfter',json.page);
						}else{
							this.error=json.msg;
						}
					}
				)
			}
        }
    });
    ap.component('m-modal',{
        template:`<div class="cu-modal" :class="[showModal?'show':'',drawer?'bottom-modal':'']" @click="close()">
            <div class="cu-dialog" @click.stop="" style="padding-bottom: 0px;">
                <div class="cu-bar bg-white solid-bottom">
                    <div class="action"><slot name="action"></slot></div>
                    <div class="action text-bold">{{title}}</div>
                    <div class="action" @click="close()">
                        <span class="cuIcon-close text-xxl text-red"></span>
                    </div>
                </div>
                <div style="max-height:550px;overflow-y: auto;" class="text-left">
                    <slot></slot>
                </div>
            </div>
        </div>`,
		props:{
			'title':{type:String,default:''},
			'drawer':{type:Boolean,default:true}
		},
		data() {
			return {
				showModal:false,
			};
		},
		methods:{
			open:function(){
				this.showModal=true;
				this.$emit("open");
			},
			close:function(){
				this.showModal=false;
				this.$emit("close");
			}
		}
    });
    ap.component('m-title',{
        template:`<div class="m-title padding-lr flex justify-between align-center">
            <div>
                <span :class="['cuIcon-titles','m-title-dot','text-blue']"></span>
            </div>
            <div class="text-lg flex-sub" :class="['text-blue']">
                <slot></slot>
            </div>
            <div style="margin-top:-6px;margin-bottom:-7px;">
                <slot name="action"></slot>
            </div>
        </div>`
    });
    ap.component('m-top',{
        template:`<div class="padding-top block"></div>`,
    });
    ap.component('m-button',{
        template:`<button class="cu-btn shadow-blur radius" :class="[clazz+color,size]"><slot></slot></button>`,
        props:{
            'type':{type:String,default:''},//error,warn,success
            'line':{type:Boolean,default:false},
            'size':{type:String,default:''}//sm,lg
        },
		data() {
			return {
			    clazz:'bg-',
				color:'blue'
			};
		},
		watch:{
			"type":function(newValue,oldValue){ this.setColor(newValue); },
			"line":function(newValue,oldValue){ this.setClazz(newValue); }
		},
		mounted(){
			this.setColor(this.type);
			this.setClazz(this.line);
		},
		methods:{
		    setColor:function(newValue){
				if(newValue=='error') this.color='red';
				else if(newValue=='warn') this.color='orange';
				else if(newValue=='success') this.color='green';
				else this.color='blue';
		    },
		    setClazz:function(newValue){
			    if(newValue) this.clazz='line-';
			    else this.clazz='bg-';
		    }
		}
    });

    //---------------------------输入组件
    ap.component('m-select-date',{
        template:`<div class="flex-sub flex">
            <input v-if="operable" type="date" v-model="dateValue" @change="dateChange" :placeholder="placeholder"></input>
            <div v-else>{{dateValue}}</div>
        </div>`,
		props:{
			'placeholder':{type:String,default:''},
			'modelValue':{type:String,default:''},
			'operable':{type:Boolean,default:true}
		},
		data() {
			return {
				dateValue:'',
			};
		},
		watch:{
			"modelValue":function(newValue,oldValue){
				this.setDateValue();
			}
		},
		mounted(){
			this.setDateValue();
		},
		methods:{
			setDateValue:function(){
				if(this.modelValue){
					this.dateValue=this.formatDate(this.modelValue,'yyyy-MM-dd');
				}else{
					this.dateValue="";
				}
			},
			dateChange:function(e){
				this.$emit('update:modelValue',this.dateValue);
				this.$emit('change',this.dateValue);
			}
		}
    });
    ap.component('m-select-dict',{
        template:`<div class="flex flex-sub">
            <div v-if="selected.value" class="flex-sub">{{selected.label}}</div>
            <div v-else-if="operable" class="flex-sub text-placeholder">{{placeholder}}</div>
            <m-button v-if="operable" @click="$refs.dictList.open()" size="sm">选择</m-button>
            <m-modal ref="dictList" :drawer="false" :title="placeholder">
                <m-card>
                    <div style="padding:2.5px;">
                        <div v-for="(item,key) in items" :key="key" class="cu-tag radius" style="margin:2.5px;" :class="[isSelect(item.value)?'bg-blue':'light']" @click="selectItem(item)">
                            {{item.label}}<span v-if="isSelect(item.value)" class="cuIcon-check"/>
                        </div>
                    </div>
                </m-card>
            </m-modal>
        </div>
        `,
		props:{
			'type':{type:String,default:''},
			'placeholder':{type:String,default:''},
			'modelValue':{type:String,default:''},
            'operable':{type:Boolean,default:true}
		},
		data() {
			return {
				selected:{},
				items:[]
			};
		},
		watch:{
			"modelValue":function(newValue,oldValue){
				this.setSelected();
			}
		},
		mounted(){
			this.initDict(this.type,(dictMap)=>{
				this.items=this.toDictOption(config.dictString[this.type]||dictMap);
				this.setSelected();
			});
		},
		methods:{
			setSelected:function(){
				if(this.modelValue){
					for(let i=0;i<this.items.length;i++){
						if(this.items[i].value==this.modelValue){
							this.selected=this.items[i];
						}
					}
				}else{
					this.selected={};
				}
			},
			selectItem:function(item){
			    this.selected=item;
				this.$emit('update:modelValue',this.selected.value);
				this.$emit('change',this.selected);
				this.$refs.dictList.close();
			},
			isSelect:function(v){
			    return this.selected.value==v
			}
		}
    });
    ap.component('m-select-color',{
        template:`<div style="padding:2.5px;" class="flex-sub">
            <template v-if="operable">
                <div v-for="(item,key) in items" :key="key" class="cu-tag radius" style="margin:2.5px;" :style="{padding:isSelect(item.value)?'0px 5px':'0px 7px'}" :class="['bg-'+item.value,light?'light':'']" @click="toggle(item.value)">
                    {{item.label}}<span v-if="isSelect(item.value)" class="cuIcon-check"/>
                </div>
            </template>
            <template v-else>
                <div v-for="(item,key) in values" :key="key" class="cu-tag radius" style="margin:2.5px;padding:0px 5px;" :class="['bg-'+item.value,light?'light':'']">
                    {{item.label}}<span class="cuIcon-check"/>
                </div>
            </template>
        </div>`,
		props:{
			'multiple':{type:Boolean,default:false},
			'modelValue':{default:''},
			'light':{type:Boolean,default:false},
            'operable':{type:Boolean,default:true}
		},
		data() {
			return {
				values:[],
				items:[
				    {value:'red',label:' '},
				    {value:'orange',label:' '},
				    {value:'yellow',label:' '},
				    {value:'olive',label:' '},
				    {value:'green',label:' '},
				    {value:'cyan',label:' '},
				    {value:'blue',label:' '},
				    {value:'purple',label:' '},
				    {value:'mauve',label:' '},
				    {value:'pink',label:' '},
				    {value:'brown',label:' '}
				]
			};
		},
		watch:{
			"modelValue":function(newValue,oldValue){
				this.setValues();
			}
		},
		mounted(){
			this.setValues();
		},
		methods:{
			setValues:function(){
				if(this.modelValue){
					this.values=this.modelValue instanceof Array?this.modelValue:[this.modelValue];
				}else{
					this.values=[];
				}
			},
			isSelect:function(v){
				return this.values.indexOf(v)>=0;
			},
			toggle:function(v){
				if(this.multiple){
					if(this.isSelect(v)){
						this.values.remove(v);
					}else{
						this.values.push(v);
					}
					let ls=[];
					for(let i=0;i<this.items.length;i++){
					    if(this.isSelect(this.items[i].value)) ls.push(this.items[i].value);
					}
					this.values=ls;
					this.$emit('update:modelValue',this.values);
				}else{
					this.values=[v];
					this.$emit('update:modelValue',this.values[0]);
				}
				this.$emit('change',this.values);
			}
		}
    });
    ap.component('m-dict-option',{
        template:`<div style="padding:2.5px;">
            <template v-if="operable">
                <div v-for="item in items" class="cu-tag radius" style="margin:2.5px;" :class="[isSelect(item.value)?'bg-blue':'light']" @click="toggle(item.value)">
                    {{item.label}}<span v-if="isSelect(item.value)" class="cuIcon-check"/>
                </div>
            </template>
            <template v-else>
                <div v-for="item in values" class="cu-tag radius bg-blue light" style="margin:2.5px;">
                    {{dict(type,item)}}<span class="cuIcon-check"/>
                </div>
            </template>
        </div>`,
		props:{
			'type':{type:String,default:''},
			'multiple':{type:Boolean,default:false},
			'modelValue':{default:''},
            'operable':{type:Boolean,default:true}
		},
		data() {
			return {
				values:[],
				items:[]
			};
		},
		watch:{
			"modelValue":function(newValue,oldValue){
				this.setValues();
			}
		},
		mounted(){
			this.initDict(this.type,(dictMap)=>{
				this.items=this.toDictOption(config.dictString[this.type]||dictMap);
				this.setValues();
			});
		},
		methods:{
			setValues:function(){
				if(this.modelValue){
					this.values=this.modelValue instanceof Array?this.modelValue:[this.modelValue];
				}else{
					this.values=[];
				}
			},
			isSelect:function(v){
				return this.values.indexOf(v)>=0;
			},
			toggle:function(v){
				if(this.multiple){
					if(this.isSelect(v)){
						this.values.remove(v);
					}else{
						this.values.push(v);
					}
					let ls=[];
					for(let i=0;i<this.items.length;i++){
					    if(this.isSelect(this.items[i].value)) ls.push(this.items[i].value);
					}
					this.values=ls;
					this.$emit('update:modelValue',this.values);
				}else{
					this.values=[v];
					this.$emit('update:modelValue',this.values[0]);
				}
				this.$emit('change',this.values);
			}
		}
    });
    ap.component('m-input-number',{
        template:`<div class="flex-sub" @click="showInput">
            <span v-if="modelValue||modelValue==0">{{formatNumber(modelValue,format)}}</span>
            <span v-else-if="operable" class="text-placeholder">{{placeholder}}</span>
            <m-modal ref="input" :title="placeholder">
                <div class="flex padding-top padding-lr align-center">
                    <div @click="toggleInputSymbol" class="padding-right"><m-button line>{{inputSymbol>0?"正":"负"}}</m-button></div>
                    <div class="flex-sub padding-lr-sm padding-tb-xs text-lg text-bold text-right light bg-blue radius">{{inputNumber}}</div>
                    <div class="padding-left"><m-button @click="inputChat()" line>⬅</m-button></div>
                </div>
                <m-card>
                    <m-grid :col="4" class="text-center text-lg text-blue text-bold">
                        <div style="width:25%;" @click="inputChat('1')" class="padding-tb solid-right solid-bottom">1</div>
                        <div style="width:25%;" @click="inputChat('2')" class="padding-tb solid-right solid-bottom">2</div>
                        <div style="width:25%;" @click="inputChat('3')" class="padding-tb solid-right solid-bottom">3</div>
                        <div style="width:25%;" @click="inputChat('+')" class="padding-tb solid-bottom">+</div>
                        <div style="width:25%;" @click="inputChat('4')" class="padding-tb solid-right solid-bottom">4</div>
                        <div style="width:25%;" @click="inputChat('5')" class="padding-tb solid-right solid-bottom">5</div>
                        <div style="width:25%;" @click="inputChat('6')" class="padding-tb solid-right solid-bottom">6</div>
                        <div style="width:25%;" @click="inputChat('-')" class="padding-tb solid-bottom">-</div>
                        <div style="width:25%;" @click="inputChat('7')" class="padding-tb solid-right solid-bottom">7</div>
                        <div style="width:25%;" @click="inputChat('8')" class="padding-tb solid-right solid-bottom">8</div>
                        <div style="width:25%;" @click="inputChat('9')" class="padding-tb solid-right solid-bottom">9</div>
                        <div style="width:25%;" @click="inputChat('*')" class="padding-tb solid-bottom">×</div>
                        <div style="width:25%;" @click="inputChat('00')" class="padding-tb solid-right">00</div>
                        <div style="width:25%;" @click="inputChat('0')" class="padding-tb solid-right">0</div>
                        <div style="width:25%;" @click="inputChat('.')" class="padding-tb solid-right">.</div>
                        <div style="width:25%;" @click="inputChat('/')" class="padding-tb">÷</div>
                    </m-grid>
                </m-card>
                <div class="flex padding-lr padding-bottom align-center">
                    <div class="flex-sub flex flex-direction padding-right">
                        <m-button @click="closeInput()" line>清空</m-button>
                    </div>
                    <div class="flex-treble flex flex-direction">
                        <m-button v-if="result" @click="closeInput(resultNumber)">{{formatNumber(resultNumber,format)}} 确定</m-button>
                        <div v-else class="text-red text-center">输入表达式错误</div>
                    </div>
                </div>
            </m-modal>
        </div>`,
		props:{
            'placeholder':{type:String,default:'请输入'},
			'modelValue':{type:Number,default:null},
			'format':{type:String,default:'#,##0.00'},
            'operable':{type:Boolean,default:true}
		},
		watch:{
			"modelValue":function(newValue,oldValue){
			    this.readInputNumber();
			    this.countResult(this.inputNumber);
			}
		},
		data() {
			return {
			    inputSymbol:1,
				inputNumber:"",
				resultNumber:0,
				result:true
			};
		},
		methods:{
		    readInputNumber:function(){
		        this.inputNumber=""+(this.modelValue==null?"":this.modelValue);
		        this.inputSymbol=(this.modelValue!=null&&this.modelValue<0)?-1:1;
		    },
		    toggleInputSymbol:function(){
		        this.inputSymbol=this.inputSymbol>0?-1:1;
		        this.countResult(this.inputNumber);
		    },
		    showInput:function(){
		        if(this.operable){
                    this.readInputNumber();
                    this.$refs.input.open();
		        }
		    },
		    closeInput:function(rn){
                this.$emit('update:modelValue',rn);
				this.$emit('change',rn);
		        this.$refs.input.close();
		    },
		    inputChat:function(n){
		        if(n) this.inputNumber+=n;
		        else if(this.inputNumber) this.inputNumber=this.inputNumber.substring(0,this.inputNumber.length-1);
		        this.countResult(this.inputNumber);
		    },
		    countResult:function(text){
		        try{
		            let n=this.formatNumber(Math.abs(eval(text))*this.inputSymbol,this.format)+"";
		            this.resultNumber=parseFloat(n.replace(/,/g,''));
		            this.result=true;
		        }catch(e){
		            this.resultNumber=null;
		            this.result=false;
		        }
		    }
		}
    });
    ap.component('m-switch',{
        template:`<div>
            <label v-if="operable" class="m-switch">
                <input type="checkbox" v-model="checkValue" @change="changeCheck">
                <div class="m-slider round"></div>
            </label>
            <div v-else class="m-switch">
                <input type="checkbox" v-model="checkValue">
                <div class="m-slider round"></div>
            </div>
        </div>`,
		props:{
			'modelValue':{type:String,default:null},
			'yesValue':{type:String,default:'Y'},
			'noValue':{type:String,default:'N'},
            'operable':{type:Boolean,default:true}
		},
		watch:{
			"modelValue":function(newValue,oldValue){
			    if(newValue==this.yesValue){
			        this.checkValue=true;
			    }else{
                    this.checkValue=false;
			    }
			}
		},
		data() {
			return {
			    checkValue:false
			};
		},
		mounted(){
		    this.checkValue=this.modelValue==this.yesValue;
		},
		methods:{
		    changeCheck:function(){
		        if(this.checkValue){
		            this.$emit('update:modelValue',this.yesValue);
                    this.$emit('change',this.yesValue);
		        }else{
		            this.$emit('update:modelValue',this.noValue);
				    this.$emit('change',this.noValue);
		        }
		    }
		}
    });
    ap.component('m-input',{
        template:`<div class="flex-sub flex">
            <div class="flex-sub flex">
                <input v-if="operable&&type=='text'" v-model="inputValue" @change="changeInput" :placeholder="placeholder"></input>
                <textarea v-else-if="operable&&type=='textarea'" v-model="inputValue" @change="changeInput" :placeholder="placeholder"></textarea>
                <div v-else>{{inputValue}}</div>
            </div>
            <div><slot></slot></div>
        </div>`,
		props:{
			'modelValue':{type:String,default:null},
			'type':{type:String,default:'text'},
            'placeholder':{type:String,default:'请输入'},
            'operable':{type:Boolean,default:true}
		},
        data() {
            return {
                inputValue:''
            };
        },
		watch:{
			"modelValue":function(newValue,oldValue){
			    this.inputValue=newValue||'';
			}
		},
		mounted(){
		    this.inputValue=this.modelValue||'';
		},
		methods:{
		    changeInput:function(){
		        this.$emit('update:modelValue',this.inputValue);
                this.$emit('change',this.inputValue);
		    }
		}
    });
    ap.component('m-form-item',{
        template:`<div class="flex-sub flex align-center">
            <div class="flex-sub"><slot></slot></div>
            <div><slot name="action"></slot></div>
        </div>`,
		props:{
		}
    });

    //---------------------------业务组件
    ap.component('index-link',{
        template:`<div class="padding-xs flex justify-center align-center" style="min-height:60px;">
            <m-icon v-if="icon" :name="icon"></m-icon>
            <div>
                <div class="text-df text-blue">{{title}}</div>
                <div v-if="desc" style="font-size: 9px;">{{desc}}</div>
            </div>
        </div>`,
		props:{
			'icon':{type:String,default:''},//
			'title':{type:String,default:''},
			'desc':{type:String,default:''}
		}
    });
    ap.component('qrcode',{
        template:`<img v-if="url" :style="{width:width,height:width}" :src="'action/base/page/qrcode?txt='+url"/>`,
		props:{
			'width':{type:String,default:'90px'},//
			'path':{type:String,default:''}
		},
		watch:{
			"path":function(newValue,oldValue){
		        this.url=encodeURIComponent(location.origin+this.path);
			}
		},
        data() {
            return {
                url:''
            };
        },
		mounted(){
		},
    });
    ap.component('status',{
        template:`<div class="cu-tag light radius" :class="'bg-'+map[type].colorMap[value]">{{text||map[type].textMap[value]}}</div>`,
		props:{
			'value':{type:String,default:''},
			'text':{type:String,default:''},
			'type':{type:String,default:'status'}
		},
        data() {
            return {
                map:{
                    'status':{
                        textMap:{'N':'停用','Y':'正常'},
                        colorMap:{'N':'red','Y':'green'}
                    },
                    'orderStatus':{
                        textMap:{'A':'暂存','N':'待确认','Y':'已确认'},
                        colorMap:{'A':'blue','N':'orange','Y':'green'}
                    },
                    'moneyRecord':{
                        textMap:{'A':'收入','B':'支出','C':'充值'},
                        colorMap:{'A':'blue','B':'orange','C':'green'}
                    },
                    'settleStatus':{
                        textMap:{'A':'结算中','N':'待结算','Y':'已结算'},
                        colorMap:{'A':'orange','N':'blue','Y':'green'}
                    }
                }
            };
        }
    });
}};